/*
 * Copyright 2000 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _WT_COLLECTION_H
#define _WT_COLLECTION_H

#include <tcl.h>

/* Collection item type */

typedef int (WtClnCompareProc) (Tcl_Obj *, Tcl_Obj *,
  int *, Tcl_Interp *);
typedef int (WtClnGetKeyProc) (Tcl_Obj *, Tcl_Obj **,
  Tcl_Interp *);
typedef int (WtClnGetValueProc) (Tcl_Obj *, Tcl_Obj **,
  Tcl_Interp *);

typedef struct WtClnItemTypeT {
  WtClnCompareProc *compare;
  WtClnGetKeyProc *getKey;
  WtClnGetValueProc *getValue;
} WtClnItemType;

/* WtCollection object. Internal only.
   Do not expose to scripts. */

typedef struct WtCollectionT {
  WtClnItemType *itemType;
  Tcl_Obj *list;
} WtCollection;

WtCollection *WtToCln(Tcl_Obj *obj);
Tcl_Obj *WtNewClnObj(Tcl_ObjType *type, WtClnItemType *itemType);
int WtClnSize(Tcl_Obj *cln, int *size, Tcl_Interp *interp);
Tcl_Obj *WtGetClnItems(Tcl_Obj *cln);
int WtGetClnKeys(Tcl_Obj *cln, Tcl_Obj **keys, Tcl_Interp *interp);
int WtGetClnValues(Tcl_Obj *cln, Tcl_Obj **values, 
  Tcl_Interp *interp);
int WtGetClnItemAtIndex(Tcl_Obj *cln, int idx, Tcl_Obj **item,
  Tcl_Interp *interp);
int WtSetClnItemAtIndex(Tcl_Obj *cln, int idx, Tcl_Obj *obj,
  Tcl_Interp *interp);
int WtAppendClnItem(Tcl_Obj *cln, Tcl_Obj *obj, Tcl_Interp *interp);
int WtAppendClnItemList(Tcl_Obj *cln, Tcl_Obj *list,
  Tcl_Interp *interp);
int WtFindClnItemIndex(Tcl_Obj *cln, Tcl_Obj *key, int start,
  int *index, Tcl_Obj **item, Tcl_Interp *interp);
int WtFindClnItemIndexReverse(Tcl_Obj *cln, Tcl_Obj *key, int start,
  int *index, Tcl_Obj **item, Tcl_Interp *interp);
int WtFindClnItem(Tcl_Obj *cln, Tcl_Obj *key, Tcl_Obj **item,
  Tcl_Interp *interp);
int WtFindAllClnItems(Tcl_Obj *cln, Tcl_Obj *key,
  Tcl_Obj **items, Tcl_Interp *interp);
int WtFindAllClnKeys(Tcl_Obj *cln, Tcl_Obj *key, Tcl_Obj **keys,
  Tcl_Interp *interp);
int WtFindAllClnValues(Tcl_Obj *cln, Tcl_Obj *key,
  Tcl_Obj **values, Tcl_Interp *interp);
int WtRemoveFromCln(Tcl_Obj *cln, Tcl_Obj *target, int limit,
  Tcl_Interp *interp);
int RemoveFromClnByIndex(Tcl_Obj *cln, int idx, Tcl_Interp *interp);
int WtRemoveFromClnByKey(Tcl_Obj *cln, Tcl_Obj *key, int limit,
  Tcl_Interp *interp);
int WtRemoveFromClnByKeyList(Tcl_Obj *cln, Tcl_Obj *list,
  int limit, Tcl_Interp *interp);
void WtClearCollection(Tcl_Obj *cln);
int WtClnToArray(Tcl_Interp *interp, Tcl_Obj *cln,
  Tcl_Obj *arrName, int multiVals);
int WtConvertToClnObj(Tcl_Obj *obj, Tcl_ObjType *type,
  Tcl_Interp *interp);
void WtClnFree(Tcl_Obj *cln);
void WtClnDup(Tcl_Obj *src, Tcl_Obj *dest);
void WtClnUpdateString(Tcl_Obj *cln);
int WtClnSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);
void WtClnObjFree(Tcl_Obj *cln);
void WtClnObjDup(Tcl_Obj *src, Tcl_Obj *dest);
void WtClnObjUpdateString(Tcl_Obj *cln);
int WtClnObjSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj,
  Tcl_ObjType *type);
int WtCompareClnItem(Tcl_Obj *cln, Tcl_Obj *item, Tcl_Obj *key,
  int *result, Tcl_Interp *interp);
int WtGetClnItemKey(Tcl_Obj *cln, Tcl_Obj *item,
  Tcl_Obj **key, Tcl_Interp *interp);
int WtGetClnItemValue(Tcl_Obj *cln, Tcl_Obj *item,
  Tcl_Obj **value, Tcl_Interp *interp);

extern struct Tcl_ObjType WtClnType;

#endif /* !_WT_COLLECTION_H */
